var CANVAS_W = 800;
var CANVAS_H = 600;
var MAX_LEVEL = 4;
var DATA = [[30, 0.7], [-30, 0.6]];
var SETTING = {start:{x:400, y:580}, angle:90.0, length:200};

function main() {
	draw_main_canvas();
	draw_data_canvas();
}

function draw_main_canvas() {
	var ctx = document.getElementById('canvas').getContext('2d');
	draw_background(ctx, '#99cc33');
	ctx.strokeStyle = "white";
	ctx.fillStyle = "white";
	draw_tree(ctx, SETTING, DATA, 1);
}

function changeLevel(v) {
	MAX_LEVEL = v;
	document.getElementById('level').textContent = v;
	draw_main_canvas();
}

function point(x, y) {
	return {x:x, y:y}
}

function A2R(angle) {
	return angle * Math.PI / 180.0;
}

function R2A(radian) {
	return radian * 180.0 / Math.PI;
}

function draw_background(ctx, color) {
	ctx.fillStyle=color;
	ctx.fillRect(0, 0, CANVAS_W, CANVAS_H);
}

function draw_line(ctx, p1, p2) {
	ctx.beginPath()
	ctx.moveTo(p1.x, p1.y);
	ctx.lineTo(p2.x, p2.y);
	ctx.stroke();
}

function line_end(p, l, angle) {
	var r = A2R(angle);
	return {x:p.x + l * Math.cos(r),
					y:p.y - l * Math.sin(r)}
}

function draw_leaf(ctx, p, l, angle) {
	var p1 = line_end(p, l, angle);
	var r = l/1.414;
	var p2 = line_end(p, r, angle + 45);
	var p3 = line_end(p, r, angle - 45);
	ctx.beginPath();
	ctx.moveTo(p.x, p.y);
	ctx.lineTo(p1.x, p1.y);
	ctx.stroke();
	ctx.beginPath();
	ctx.moveTo(p.x, p.y);
	ctx.arcTo(p2.x,p2.y, p1.x, p1.y, r);
	ctx.arcTo(p3.x,p3.y, p.x, p.y, r);
	ctx.stroke();
}

function draw_polygon(ctx, points, fill) {
	if(points.length > 2) { 
		var i;
		var p = points[0];
		ctx.beginPath();
		ctx.moveTo(p.x, p.y);
		for(i = 1; i < points.length; ++i) {
			p = points[i];
			ctx.lineTo(p.x, p.y);
		}
		ctx.closePath();
		if(fill) {
			ctx.fill();
		} else {
			ctx.stroke();
		}
	}
}

function draw_trunk(ctx, p, l, a) {
	var w1 = l / 25, w2 = l / 40;
	var p1 = line_end(p, w1, a + 90);
	var p2 = line_end(p, w1, a - 90);
	var t = line_end(p, l, a);
	var p3 = line_end(t, w2, a + 90);
	var p4 = line_end(t, w2, a - 90);
	draw_polygon(ctx, [p1,p2,p4,p3], true);
}

function draw_tree(ctx, s, data, level) {
	var i;
	var a = s.angle;
	var l = s.length;
	draw_trunk(ctx, s.start, l, a); 
	if(level <= MAX_LEVEL) {	
		var p = line_end(s.start, l, a);
		for(i = 0; i < data.length; ++i) {
			var b = data[i];
			var s2 = {start:p, angle:a + b[0], length:l * b[1]};
			draw_tree(ctx, s2, data, level + 1);
		}
	} else {
		var dl = l / 3;
		var p = s.start;
		for(i = 0; i < 3; ++i) {
			p = line_end(p, dl, a);
			draw_leaf(ctx, p, dl, a + 30);
			draw_leaf(ctx, p, dl, a - 30);
		}
	}
}

var CANVAS2_W = 320;
var CANVAS2_X0 = CANVAS2_W/2;
var CANVAS2_LEN = CANVAS2_X0 - 10;
var CANVAS2_ORI = point(CANVAS2_X0, CANVAS2_X0);

function draw_circle(ctx, p, r, fill) {
	ctx.beginPath()
	ctx.arc(p.x, p.y, r, 0, Math.PI * 2);
	if(fill) {
		ctx.fill();
	} else {
		ctx.stroke();
	}
}

var EDITING = -1;
var EDITED = false
var DATA_ENDS = [];

function ends_from_data(data) {
	var i;
	DATA_ENDS = []
	for(i = 0; i < data.length; ++i) {
		var b = data[i];
		DATA_ENDS.push(line_end(CANVAS2_ORI, CANVAS2_LEN*b[1], b[0] + 90));
	} 
}

function data_from_ends() {
	var i;
	var data = []
	for(i = 0;i < DATA_ENDS.length; ++i) {
		var p = DATA_ENDS[i];
		var dx = p.x - CANVAS2_ORI.x;
		var dy = p.y - CANVAS2_ORI.y;
		var s = Math.sqrt(dx*dx + dy*dy) / CANVAS2_LEN;
    var a = dx == 0 ? 0 : ((dx > 0 ? -90 : 90) - R2A(Math.atan(dy / dx)));
		data.push([a, s]);
	}
	return data;
}

function find_ends(x, y) {
	var i;
	for(i = DATA_ENDS.length - 1; i >= 0; --i) {
		var b = DATA_ENDS[i];
		if(Math.abs(b.x - x) < 5 && Math.abs(b.y - y) < 5) {
			break;
		}
	}
	return i;
}

function undo_editing() {
	if(EDITED) {
		EDITED = false;
		draw_data_canvas();
	}
}

function save_editing() {
	if(EDITED) {
		EDITED = false;
		DATA = data_from_ends();
		draw_main_canvas();
	}
}

function print_data(data) {
	var strs = []
	for(i = 0; i < data.length; ++i) {
		var a = Math.round(data[i][0]);
		var s = Math.round(data[i][1]*100) / 100;
		strs.push("<" + a+"°,"+ s + ">");
	}
	document.getElementById('data').textContent = "{" + strs.join(", ") + "}";
}

function draw_data_ends(ctx) {
	var i;
	ctx.clearRect(0, 0, CANVAS2_W, CANVAS2_W);
	ctx.strokeStyle = "#ececec";
	ctx.setLineDash([3, 3]);
	draw_circle(ctx, CANVAS2_ORI, CANVAS2_LEN, false);
	ctx.setLineDash([]);
  ctx.lineWidth = 2;
	draw_line(ctx, CANVAS2_ORI, 
						point(CANVAS2_X0, CANVAS2_X0 + CANVAS2_LEN)); 
	ctx.fillStyle = "red";
	for(i = 0; i < DATA_ENDS.length; ++i) {
		var p2 = DATA_ENDS[i];
		draw_line(ctx, CANVAS2_ORI, p2);
		draw_circle(ctx, p2, 3, true);
	}
}


function dist(p1, p2) {
	var dx = p1.x - p2.x;
	var dy = p1.y - p2.y;
	return Math.sqrt(dx*dx + dy*dy);
}

function end_editing() {
	EDITING = -1
}

function update_data(i, x, y) {
	var p = point(x,y);
	DATA_ENDS[i] = p;
	EDITED = true;
	if(dist(CANVAS2_ORI, p) >= CANVAS2_LEN) {
		end_editing();
	}
	print_data(data_from_ends());
}

function draw_data_canvas() {
	var canvas = document.getElementById('canvas2')
	var ctx = canvas.getContext('2d');
	ends_from_data(DATA);
	draw_data_ends(ctx);
	print_data(DATA);
	canvas.addEventListener("mousedown", 
							function (e) {
							EDITING = find_ends(e.offsetX, e.offsetY);
							}, false);
	canvas.addEventListener("mouseup", 
							function (e) {
							if(EDITING >= 0) {
								end_editing();
							}
							}, false);
	canvas.addEventListener("mousemove", 
							function (e) {
							if(EDITING >= 0) {
							update_data(EDITING, e.offsetX, e.offsetY);
							draw_data_ends(ctx);
							}
						}, false);
	
}

